package com.bjc.base.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

/**
 * mybatis 配置postgresql主数据源
 * 
 * @author 许自辉
 * @date 2017年7月11日 下午4:29:24
 */
@Configuration
// 扫描 Mapper 接口并容器管理
@MapperScan(basePackages = "com.bjc.**.dao", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MybatisConfiguration {

	// mybatis配置文件路径
	@Value("${mybatis.config-location}")
	private String configLocation;
	// mybatis mapper文件路径
	@Value("${mybatis.mapper-locations}")
	private String mapperLocations;
	// dao 文件路径
	@Value("${mybatis.type-aliases-package}")
	private String typeAliasesPackage;

	@Bean
	public WallConfig wallConfig() {
		WallConfig config = new WallConfig();
		config.setMultiStatementAllow(true);// 允许一次执行多条语句
		config.setDeleteAllow(true);// 允许一次删除多条
		config.setCommentAllow(true);// 允许注释
		config.setNoneBaseStatementAllow(true);// 允许非基本语句的其他语句
		return config;
	}

	@Bean
	public WallFilter wallFilter() {
		WallFilter wallFilter = new WallFilter();
		wallFilter.setConfig(wallConfig());
		return wallFilter;
	}

	@Bean(name = "masterDataSource")
	@Primary
	public DataSource druidDataSource(Environment env) {
		DruidDataSource dataSource = DruidDataSourceBuilder.create().build(env, "spring.datasource.druid.");
		List<Filter> filterList = new ArrayList<>();
		filterList.add(wallFilter());
		dataSource.setProxyFilters(filterList);// 添加自定义Filter
		// ...进行其他配置
		return dataSource;
	}

	@Bean(name = "masterSqlSessionFactory")
	@Primary
	public SqlSessionFactory sqlSessionFactoryBean(@Qualifier("masterDataSource") DataSource masterDataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setConfigLocation(new ClassPathResource(configLocation));
		bean.setDataSource(masterDataSource);
		bean.setTypeAliasesPackage(typeAliasesPackage);
		// 分页插件
		// PageInterceptor pageHelper = new PageInterceptor();
		// Properties properties = new Properties();
		// properties.setProperty("helperDialect", "postgresql");
		// properties.setProperty("reasonable", "true");
		// properties.setProperty("supportMethodsArguments", "true");
		// properties.setProperty("returnPageInfo", "check");
		// properties.setProperty("params", "count=countSql");
		// pageHelper.setProperties(properties);
		// PageInterceptor[] plugins = new PageInterceptor[]{pageHelper};
		// bean.setPlugins(plugins);
		// 添加XML目录
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		bean.setMapperLocations(resolver.getResources(mapperLocations));
		return bean.getObject();
	}

	@Bean
	@Primary
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

	@Bean(name = "masterTransactionManager")
	@Primary
	public DataSourceTransactionManager masterTransactionManager(
			@Qualifier("masterDataSource") DataSource masterDataSource) throws Exception {
		return new DataSourceTransactionManager(masterDataSource);
	}

}
